// myMatchTemplate.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
int x = 0, y = 0;

double EM(unsigned char* pModel, int width, int height)
{
	double sum = 0;
	for(int i=0; i<height; i++)
	{
		for(int j=0; j<width; j++)
		{
			sum+=*(pModel+i*width+j);
		}
	}
	return sum;
}

double EM2(unsigned char* pModel, int width, int height)
{
	double s;
	double sum = 0;
	for(int i=0; i<height; i++)
	{
		for(int j=0; j<width; j++)
		{
			s=*(pModel+i*width+j);
			sum+=s*s;
		}
	}
	return sum;
}

void allSum(unsigned char *pToSearch, int l, int h, int u, int v, unsigned char *pModel, int width, int height, double *pI, double *pI2, double *pIM)
{
	unsigned char *pUV = pToSearch+v*l+u;
	double s, t;
	*pI = *pI2 = *pIM = 0;
	for(int i=0; i<height; i++)
	{
		for(int j=0; j <width; j++)
		{
			s = *pUV;
			t = *(pModel+i*width+j);
			*pI += s;
			*pI2 += s*s;
			*pIM += s*t;
			pUV++;
		}
		pUV+=(l-width);
	}
}

CvPoint Match(unsigned char *pToSearch, int l, int h, unsigned char *pModel, int width, int height)
{
	CvPoint cvPt = cvPoint(0,0);
	int uMax = l-width;
	int vMax = h-height;
	long N = width*height;

	double M = EM(pModel,width,height);
	double M2 = EM2(pModel,width,height);
	double I, I2, IM;
	double val = -1;
	for(int p=0; p<=uMax; p++)
	{
		for(int q=0; q<=vMax; q++)
		{
			allSum(pToSearch, l, h, p, q, pModel, width, height, &I, &I2, &IM);

			//printf("%f \n", (N*IM-I*M));
			double numberator = (N*IM-I*M)*(N*IM-I*M);
			double denominator = (N*I2-I*I)*(N*M2-M*M);
			double ret = numberator/denominator;
			if(ret > val){
				x = p;
				y = q;
				val = ret;
			}
		}
	}
	printf("val: %f x: %d y: %d\n", val, x, y);
	cvPt.x = x;
	cvPt.y = y;

	return cvPt;
}

int _tmain(int argc, _TCHAR* argv[])
{
#if 1
	IplImage * image= cvLoadImage("..\\..\\niu.jpg", 0);
	IplImage * temp= cvLoadImage("..\\..\\temp.png", 0);
#else
	IplImage * image= cvLoadImage("..\\..\\c.jpg", 0);
	IplImage * temp= cvLoadImage("..\\..\\1.png", 0);
#endif
	unsigned char *pImg = NULL;
	unsigned char *pTemp = NULL;

	if(!image || !temp)
		goto End;

	pImg = (unsigned char *)malloc(image->width*image->height);
	pTemp = (unsigned char *)malloc(temp->width*temp->height);
	if(!pImg || !pTemp)
		goto End;

	for(int i = 0; i < image->height; i++){
		memcpy(pImg+i*image->width, image->imageData+i*image->widthStep, image->width);
	}
	for(int i = 0; i < temp->height; i++){
		memcpy(pTemp+i*temp->width, temp->imageData+i*temp->widthStep, temp->width);
	}

	Match(pImg, image->width, image->height, pTemp, temp->width, temp->height);
	cvRectangle(image, cvPoint(x,y), cvPoint(x+temp->width,y+temp->height), cvScalar(0,0,0), 2);

	cvShowImage("temp", temp);
	cvShowImage("result", image);
	cv::waitKey(0);

End:
	if(image)
		cvReleaseImage(&image);
	if(temp)
		cvReleaseImage(&temp);
	if(pImg)
		free(pImg);
	if(pTemp)
		free(pTemp);

	return 0;
}

